package Vue;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.util.ArrayList;

import agent.Aboiement;
import agent.Agent;
import agent.Chien;
import agent.Mouton;

import obstacle.Bergerie;
import obstacle.Eau;
import obstacle.Feu;
import obstacle.IObstacle;
import obstacle.Ligne;
import obstacle.Montagne;
import obstacle.ObstaclePolygone;
import obstacle.Trou;

import AEtoile.AStar;

import reseau.Coordonnees2D;
import reseau.Reseau;
import reseau.WayPoint;

public class Terrain 
{
	int _dx;
	int _dy;
	
	int Buffer0[][][];
	int Buffer1[][][];
	
	boolean buffering;
	boolean cloneBuffer; // if buffering, clone buffer after swith
	private ArrayList<agent.Chien> _chiens;
	private ArrayList<agent.Mouton> _moutons;
	private ArrayList<Aboiement> _aboiements;
	//private ArrayList<WayPoint> _wps;
	private AStar _astar;
	private Reseau _reseau;
 	private ArrayList<IObstacle> _lstObstacles;
 	private Bergerie _bergerie;
 	private int _nbMoutons;
 	private Coordonnees2D objectif;
 	//ArrayList<Polygon> _lstPolygon;
	//obstacle
	int activeIndex;
	
	
	public Terrain ( int __dx , int __dy, boolean __buffering, boolean __cloneBuffer )
	{
		_dx = __dx;
		_dy = __dy;
		
		buffering = __buffering;
		cloneBuffer = __cloneBuffer;
		
		Buffer0 = new int[_dx][_dy][3];
		Buffer1 = new int[_dx][_dy][3];
		activeIndex = 0;
		_nbMoutons = 10;
		objectif =new Coordonnees2D(700,650);
		
		//this._wps = new ArrayList<WayPoint>();
		this._lstObstacles = new ArrayList<IObstacle>();
		this.initReseau(); 
		this.initObstacle();
		this._astar = new AStar(this._reseau);
	    //initialiser les chiens
		this.initChiens();
		//initialiser les moutons
		this.initMoutons();
		
		this._aboiements = new ArrayList<Aboiement>();
		
		this.initBuffer();
	}
	
//	public void setObjectif(Coordonnees2D objectif)
//	{ this._agents.get(0).setObjectif(objectif); }
//	
	public void checkBounds( int __x , int __y )
	{
		if ( __x < 0 || __x > _dx || __y < 0 || __y > _dy )
		{
			System.err.println("[error] out of bounds ("+__x+","+__y+")");
			System.exit(-1);
		}
	}
	
	public int[] getCellState ( int __x, int __y )
	{
		checkBounds (__x,__y);
		
		int color[] = new int[3];

		if ( buffering == false )
		{
			color[0] = Buffer0[__x][__y][0];
			color[1] = Buffer0[__x][__y][1];
			color[2] = Buffer0[__x][__y][2];
		}
		else
		{
			if ( activeIndex == 1 ) // read old buffer
			{
				color[0] = Buffer0[__x][__y][0];
				color[1] = Buffer0[__x][__y][1];
				color[2] = Buffer0[__x][__y][2];
			}
			else
			{
				color[0] = Buffer1[__x][__y][0];
				color[1] = Buffer1[__x][__y][1];
				color[2] = Buffer1[__x][__y][2];
			}
		}
		
		return color;
	}
	
	public void setCellState ( int __x, int __y, int __r, int __g, int __b )
	{
		checkBounds (__x,__y);
		
		if ( buffering == false )
		{
			Buffer0[__x][__y][0] = __r;
			Buffer0[__x][__y][1] = __g;
			Buffer0[__x][__y][2] = __b;
		}
		else
		{
			if ( activeIndex == 0 ) // write new buffer
			{
				Buffer0[__x][__y][0] = __r;
				Buffer0[__x][__y][1] = __g;
				Buffer0[__x][__y][2] = __b;
			}
			else
			{
				Buffer1[__x][__y][0] = __r;
				Buffer1[__x][__y][1] = __g;
				Buffer1[__x][__y][2] = __b;
			}
		}
	}
	
	public void setCellState ( int __x, int __y, int __color[] )
	{
		checkBounds (__x,__y);
			
		if ( buffering == false )
		{
			Buffer0[__x][__y][0] = __color[0];
			Buffer0[__x][__y][1] = __color[1];
			Buffer0[__x][__y][2] = __color[2];
		}
		else
		{
			if ( activeIndex == 0 )
			{
				Buffer0[__x][__y][0] = __color[0];
				Buffer0[__x][__y][1] = __color[1];
				Buffer0[__x][__y][2] = __color[2];
			}
			else
			{
				Buffer1[__x][__y][0] = __color[0];
				Buffer1[__x][__y][1] = __color[1];
				Buffer1[__x][__y][2] = __color[2];
			}	
		}
	}
	
	/**
	 * Update the world state and return an array for the current world state (may be used for display)
	 * @return
	 */
	public void step ( )
	{
		if(this._bergerie.getCompteur() != this._nbMoutons )
		{
			stepWorld();
			stepAgents();
		}
		
		
		if ( buffering && cloneBuffer )
		{
			if ( activeIndex == 0 )
				for ( int x = 0 ; x != _dx ; x++ )
					for ( int y = 0 ; y != _dy ; y++ )
					{
						Buffer1[x][y][0] = Buffer0[x][y][0];
						Buffer1[x][y][1] = Buffer0[x][y][1];
						Buffer1[x][y][2] = Buffer0[x][y][2];
					}
			else
				for ( int x = 0 ; x != _dx ; x++ )
					for ( int y = 0 ; y != _dy ; y++ )
					{
						Buffer0[x][y][0] = Buffer1[x][y][0];
						Buffer0[x][y][1] = Buffer1[x][y][1];
						Buffer0[x][y][2] = Buffer1[x][y][2];
					}

			activeIndex = (activeIndex + 1 ) % 2; // switch buffer index
		}

	}
	
	public int[][][] getCurrentBuffer()
	{
		if ( activeIndex == 0 || buffering == false ) 
			return Buffer0;
		else
			return Buffer1;		
	}
	
	public int getWidth()
	{
		return _dx;
	}
	
	public int getHeight()
	{
		return _dy;
	}
	
	public int get_dx() {
		return _dx;
	}

	public int get_dy() {
		return _dy;
	}

	public ArrayList<Chien> get_agents() 
	{ return _chiens; }

	public AStar get_astar() 
	{ return _astar; }

	public Reseau get_reseau() 
	{ return _reseau; }

	public ArrayList<IObstacle> get_lstObstacles() 
	{ return _lstObstacles;	}
	
	public void addChien(Chien agent)
	{
		this._chiens.add(agent);
	}
	public void addMouton(Mouton agent)
	{
		this._moutons.add(agent);
	}
	public void addObstacle(IObstacle obs)
	{
		this._lstObstacles.add(obs);
	}
//	public void addWayPoint(WayPoint wp)
//	{
//		this._wps.add(wp);
//	}
//	
	public void ajouterAboiement(Aboiement aboiement)
	{ this._aboiements.add(aboiement); }
	
	public ArrayList<Aboiement> getAboiements()
	{ return this._aboiements; }
	
	public void stepWorld() // world THEN agents
	{
		// ...
		for(int i=0; i< this._moutons.size(); i++)
		{
			if(this.arriverAuBergerie((int)this._moutons.get(i).getPosition().getX(), (int)this._moutons.get(i).getPosition().getY() ))
			{
				this._moutons.remove(i);
				//_nbMoutons--;
				this._bergerie.incrementCompteur();
				i--;				
			}
			else if(this.mourir((int)this._moutons.get(i).getPosition().getX(), (int)this._moutons.get(i).getPosition().getY()))
			{
				this._moutons.remove(i);
				_nbMoutons--;
				i--;
			}
		}
		
	}
	
	public void stepAgents() // agents
	{
		boolean aboiement = false;
		for(int i =0; i < this._chiens.size(); i++)
		{
			this._chiens.get(i).avancer();
			if(Math.random() > 0.2)
			{
				aboiement =true;
				this._chiens.get(i).aboyer();
				//System.out.println("aboyer");
			}
		}
		if(aboiement)
		{
			for(int i=0; i<this._moutons.size(); i++)
			{
				this._moutons.get(i).deciderObjectif();
				this._moutons.get(i).avancer();
			}
		}
		
		// on supprime les aboiements courants
		this._aboiements.clear();
	}
	
	public void display( CAImageBuffer image )
	{
		//ici on dessine les obstacle
//		for(int i=0; i<this._lstObstacles.size(); i++)
//		{
//			ArrayList<Coordonnees2D> sommets = ((ObstaclePolygone)this._lstObstacles.get(i)).getSommets();
//			Polygon polygon = new Polygon();
//			for(int j=0; j < sommets.size(); j++)
//			{
//				polygon.addPoint((int)sommets.get(j).getX(), (int)sommets.get(j).getY());
//			}
//			Graphics2D g;
//			g =image.createGraphics(); 
//			g.setColor(new Color(255,128,0));
//			g.drawPolygon(polygon);
//			g.fillPolygon(polygon);			
//		}
		image.update(this.getCurrentBuffer());
		
		for(int i =0; i < this._moutons.size(); i++)
		{
			this._moutons.get(i).display(image.createGraphics());
		}
		//this._bergerie.display(image.createGraphics());
		this.drawObstacle();
		drawBergerie();
		for(int i =0; i < this._chiens.size(); i++)
		{
			this._chiens.get(i).display(image.createGraphics());
		}
	}
	public String getTips(int x, int y)
	{
		String tips ="";
		return tips;
	}
	public ArrayList<WayPoint> getSolutionParAstar(WayPoint start, WayPoint end)
	{
		//il faut configurer le res;
		this._astar.setWPs(start, end);
		return this._astar.resolution();
	}
	private void initReseau()
	{
		this._reseau = new Reseau(16);
		_reseau.ajouterWayPoint(110,610);
		_reseau.ajouterWayPoint(220,400);
		_reseau.ajouterWayPoint(220,600);
		_reseau.ajouterWayPoint(280,310);
		_reseau.ajouterWayPoint(300,90);
		_reseau.ajouterWayPoint(420,310);
		_reseau.ajouterWayPoint(530,360);
		_reseau.ajouterWayPoint(650,140);
		_reseau.ajouterWayPoint(700,380);
		_reseau.ajouterWayPoint(620,600);
		_reseau.ajouterWayPoint(700,770);
		_reseau.ajouterWayPoint(810,760);
		_reseau.ajouterWayPoint(410,540);
		_reseau.ajouterWayPoint(520,490);
		_reseau.ajouterWayPoint(540,720);
		_reseau.ajouterWayPoint(410,655);
//	
//		obs.add(new Coordonnees2D(420, 550));
//		obs.add(new Coordonnees2D(500, 500));
//		obs.add(new Coordonnees2D(530, 700));
//		obs.add(new Coordonnees2D(420, 640));
//	
//		
		
		
		_reseau.ajouterLienBidirectionnel(0, 1);
		_reseau.ajouterLienBidirectionnel(0, 2);
		_reseau.ajouterLienBidirectionnel(1, 2);
		_reseau.ajouterLienBidirectionnel(1, 3);
		_reseau.ajouterLienBidirectionnel(1, 4);
		_reseau.ajouterLienBidirectionnel(1, 5);
		//_reseau.ajouterLienBidirectionnel(1, 9);
		//_reseau.ajouterLienBidirectionnel(1, 10);
		//_reseau.ajouterLienBidirectionnel(1, 11);
		_reseau.ajouterLienBidirectionnel(1, 12);
		_reseau.ajouterLienBidirectionnel(1, 13);
		_reseau.ajouterLienBidirectionnel(1, 15);
		_reseau.ajouterLienBidirectionnel(2, 3);
		_reseau.ajouterLienBidirectionnel(2, 5);
		_reseau.ajouterLienBidirectionnel(2, 6);
		//_reseau.ajouterLienBidirectionnel(2, 8);
		//_reseau.ajouterLienBidirectionnel(2, 9);
		_reseau.ajouterLienBidirectionnel(2, 10);
		_reseau.ajouterLienBidirectionnel(2, 12);
		_reseau.ajouterLienBidirectionnel(2, 13);
		_reseau.ajouterLienBidirectionnel(2, 14);
		_reseau.ajouterLienBidirectionnel(2, 15);
		_reseau.ajouterLienBidirectionnel(3, 4);
		_reseau.ajouterLienBidirectionnel(3, 5);
		//_reseau.ajouterLienBidirectionnel(3, 9);
		_reseau.ajouterLienBidirectionnel(3, 11);
		_reseau.ajouterLienBidirectionnel(3, 12);
		_reseau.ajouterLienBidirectionnel(3, 13);
		_reseau.ajouterLienBidirectionnel(3, 15);
		_reseau.ajouterLienBidirectionnel(4, 5);
		_reseau.ajouterLienBidirectionnel(4, 6);
		_reseau.ajouterLienBidirectionnel(4, 7);
		_reseau.ajouterLienBidirectionnel(5, 6);
		_reseau.ajouterLienBidirectionnel(5, 7);
		_reseau.ajouterLienBidirectionnel(5, 9);
		_reseau.ajouterLienBidirectionnel(5, 11);
		_reseau.ajouterLienBidirectionnel(5, 12);
		_reseau.ajouterLienBidirectionnel(5, 13);
		_reseau.ajouterLienBidirectionnel(6, 7);
		_reseau.ajouterLienBidirectionnel(6, 8);
		_reseau.ajouterLienBidirectionnel(6, 9);
		_reseau.ajouterLienBidirectionnel(6, 11);
		_reseau.ajouterLienBidirectionnel(6, 12);
		_reseau.ajouterLienBidirectionnel(6, 13);
		_reseau.ajouterLienBidirectionnel(7, 8);
		_reseau.ajouterLienBidirectionnel(8, 9);
		_reseau.ajouterLienBidirectionnel(8, 11);
		_reseau.ajouterLienBidirectionnel(8, 12);
		_reseau.ajouterLienBidirectionnel(9, 10);
		_reseau.ajouterLienBidirectionnel(9, 11);
		_reseau.ajouterLienBidirectionnel(9, 13);
		_reseau.ajouterLienBidirectionnel(9, 14);
		_reseau.ajouterLienBidirectionnel(10, 11);
		_reseau.ajouterLienBidirectionnel(10, 13);
		_reseau.ajouterLienBidirectionnel(10, 14);
		_reseau.ajouterLienBidirectionnel(12, 13);
		_reseau.ajouterLienBidirectionnel(12, 15);
		_reseau.ajouterLienBidirectionnel(13, 14);
		_reseau.ajouterLienBidirectionnel(14, 15);
		//_reseau.ajouterLienBidirectionnel(1, 11);
	}
	private void initObstacle()
	{
		ArrayList<Coordonnees2D> obs = new ArrayList<Coordonnees2D>();
		obs.add(new Coordonnees2D(120, 600));
		obs.add(new Coordonnees2D(220, 410));
		obs.add(new Coordonnees2D(220, 600));
		this._lstObstacles.add(new Feu(obs,this));
		obs.clear();
		obs.add(new Coordonnees2D(300, 300));
		obs.add(new Coordonnees2D(300, 100));
		obs.add(new Coordonnees2D(400, 300));
		this._lstObstacles.add(new Eau(obs,this));
		obs.clear();
		obs.add(new Coordonnees2D(550, 350));
		obs.add(new Coordonnees2D(650, 150));
		obs.add(new Coordonnees2D(680, 370));
		this._lstObstacles.add(new Trou(obs,this));
		obs.clear();
		obs.add(new Coordonnees2D(420, 550));
		obs.add(new Coordonnees2D(500, 510));
		obs.add(new Coordonnees2D(530, 700));
		obs.add(new Coordonnees2D(420, 640));
		this._lstObstacles.add(new Montagne(obs,this));
		obs.clear();
//		obs.add(new Coordonnees2D(600, 600));
//		obs.add(new Coordonnees2D(700, 750));
//		obs.add(new Coordonnees2D(800, 650));
		obs.add(new Coordonnees2D(680, 600));
		obs.add(new Coordonnees2D(720, 600));
		obs.add(new Coordonnees2D(750, 640));
		obs.add(new Coordonnees2D(750, 680));
		obs.add(new Coordonnees2D(720, 720));
		obs.add(new Coordonnees2D(680, 720));
		obs.add(new Coordonnees2D(650, 680));
		obs.add(new Coordonnees2D(650, 640));
		//this._lstObstacles.add(new Bergerie(obs,this));
		_bergerie = new Bergerie(obs,this);
		
		//obstacle autour de terrain
//		this._lstObstacles.add(new Ligne(new Coordonnees2D(0, 0),new Coordonnees2D(this.getWidth()-1, 0),this));
//		this._lstObstacles.add(new Ligne(new Coordonnees2D(0, this.getHeight()-1),new Coordonnees2D(this.getWidth()-1, this.getHeight()-1),this));
//		this._lstObstacles.add(new Ligne(new Coordonnees2D(0, 0),new Coordonnees2D(0, this.getHeight()-1),this));
//		this._lstObstacles.add(new Ligne(new Coordonnees2D(this.getWidth()-1, 0),new Coordonnees2D(this.getWidth()-1, this.getHeight()-1),this));
		int largeur = 5;
		obs.clear();
		obs.add(new Coordonnees2D(0, 0));
		obs.add(new Coordonnees2D(this.getWidth(), 0));
		obs.add(new Coordonnees2D(this.getWidth(), largeur));
		obs.add(new Coordonnees2D(0, largeur));
		this._lstObstacles.add(new Eau(obs,this));
		obs.clear();
		obs.add(new Coordonnees2D(0, largeur));
		obs.add(new Coordonnees2D(largeur, largeur));
		obs.add(new Coordonnees2D(largeur, this.getHeight()));
		obs.add(new Coordonnees2D(0, this.getHeight()));
		this._lstObstacles.add(new Eau(obs,this));
		obs.clear();
		obs.add(new Coordonnees2D(0, this.getHeight()-largeur));
		obs.add(new Coordonnees2D(this.getWidth(), this.getHeight()-largeur));
		obs.add(new Coordonnees2D(this.getWidth(), this.getHeight()));
		obs.add(new Coordonnees2D(0, this.getHeight()));
		this._lstObstacles.add(new Eau(obs,this));
		obs.clear();
		obs.add(new Coordonnees2D(this.getWidth()-largeur, largeur));
		obs.add(new Coordonnees2D(this.getWidth(), largeur));
		obs.add(new Coordonnees2D(this.getWidth(), this.getHeight() ));
		obs.add(new Coordonnees2D(this.getWidth()-largeur, this.getHeight()));
		this._lstObstacles.add(new Eau(obs,this));
	}
	private boolean isInObstacle( int x, int y)
	{
		for(int i=0; i<this._lstObstacles.size(); i++)
		{
			if((_lstObstacles.get(i)).contient(new Coordonnees2D(x,y)))
			{
				return true;
			}
		}
		return false;
	}
	private void initBuffer()
	{
//		_lstPolygon = new ArrayList<Polygon>();
//		for(int i=0; i<this._lstObstacles.size(); i++)
//		{
//			ArrayList<Coordonnees2D> sommets = ((ObstaclePolygone)this._lstObstacles.get(i)).getSommets();
//			Polygon polygon = new Polygon();
//			for(int j=0; j < sommets.size(); j++)
//			{
//				polygon.addPoint((int)sommets.get(j).getX(), (int)sommets.get(j).getY());
//			}
//			//g.setColor(new Color(255,128,0));			
//			lstPolygon.add(polygon);
//		}
		
		for ( int x = 0 ; x != _dx ; x++ )
		{
	    	for ( int y = 0 ; y != _dy ; y++ )
	    	{
	    		if( !this.isInObstacle(x, y))
	    		{
	    			Buffer0[x][y][0]=255;
					Buffer0[x][y][1]=255;
					Buffer0[x][y][2]=255;
					Buffer1[x][y][0]=255;
					Buffer1[x][y][1]=255;
					Buffer1[x][y][2]=255;
	    		}
	    	}
		}
		this.drawObstacle();
	}
	private void drawObstacle()
	{
		for(int i=0; i<this._lstObstacles.size(); i++)
		{
			this._lstObstacles.get(i).display(null);
//			ObstaclePolygone obs= (ObstaclePolygone) this._lstObstacles.get(i);
//			Point leftUp = new Point((int)obs.getSommets().get(0).getX(),(int)obs.getSommets().get(0).getY());
//			Point rightDown = new Point(leftUp);
//			Polygon polygon = new Polygon();
//			polygon.addPoint(leftUp.x, leftUp.y);
//			for(int j=1; j<obs.getSommets().size(); j++)
//			{
//				polygon.addPoint((int)obs.getSommets().get(j).getX(),(int)obs.getSommets().get(j).getY());
//				if((int)obs.getSommets().get(j).getX() < leftUp.getX())
//				{
//					leftUp.x = (int)obs.getSommets().get(j).getX();
//				}
//				if((int)obs.getSommets().get(j).getY() < leftUp.getY())
//				{
//					leftUp.y = (int)obs.getSommets().get(j).getY();
//				}
//				if((int)obs.getSommets().get(j).getX() > rightDown.getX())
//				{
//					rightDown.x = (int)obs.getSommets().get(j).getX();
//				}
//				if((int)obs.getSommets().get(j).getY() > rightDown.getY())
//				{
//					rightDown.y = (int)obs.getSommets().get(j).getY();
//				}
//			}
//			for(int px=leftUp.x; px <= rightDown.x; px++)
//			{
//				for(int py=leftUp.y; py <= rightDown.y; py++)
//				{
//					if(polygon.contains(px, py))
//					{
//						//System.out.println("r:"+obs.getRedValue()+"  g:"+obs.getGreenValue()+"  b:"+obs.getBlueValue());
//						//this.setCellState(py, py, obs.getRedValue(), obs.getGreenValue(), obs.getBlueValue());
//		    			Buffer0[px][py][0]=obs.getRedValue();
//						Buffer0[px][py][1]=obs.getGreenValue();
//						Buffer0[px][py][2]=obs.getBlueValue();
//						Buffer1[px][py][0]=obs.getRedValue();
//						Buffer1[px][py][1]=obs.getGreenValue();
//						Buffer1[px][py][2]=obs.getBlueValue();					
//					}
//				}
//			}
		}
	}
	private void drawBergerie()
	{
		this._bergerie.display(null);
		for(int i=0; i<this._bergerie.getSommets().size() - 1; i++)
		{
			Polygon polygon = new Polygon();
			Coordonnees2D point1 = _bergerie.getSommets().get(i);
			Coordonnees2D point2 = _bergerie.getSommets().get(i+1);
			polygon.addPoint((int)point1.getX(), (int)point1.getY());
			polygon.addPoint((int)point1.getX()+1, (int)point1.getY()+1);
			polygon.addPoint((int)point2.getX()+1, (int)point2.getY()+1);
			polygon.addPoint((int)point2.getX(), (int)point2.getY());
			int px1 = (point1.getX() > point2.getX())? (int)point2.getX():(int)point1.getX();
			int px2 = (point1.getX() > point2.getX())? (int)point1.getX():(int)point2.getX();
			int py1 = (point1.getY() > point2.getY())? (int)point2.getY():(int)point1.getY();
			int py2 = (point1.getY() > point2.getY())? (int)point1.getY():(int)point2.getY();
			//System.out.println("draw bergerie x1:"+px1+"  py1:"+py1+"   px2:"+px2+" py2:"+py2);
			for(int index1=px1; index1<=px2; index1++)
			{
				for(int index2=py1; index2<=py2; index2++)
				{
					if(polygon.contains(index1, index2))
					{
						initBuffer(index1, index2, 128, 128, 64);
						initBuffer(index1+1, index2+1, 128, 128, 64);
						initBuffer(index1-1, index2-1, 128, 128, 64);
					}
				}
			}
		}
		if(_bergerie.getSommets().size() > 2)
		{
			Polygon polygon = new Polygon();
			Coordonnees2D point1 = _bergerie.getSommets().get(0);
			Coordonnees2D point2 = _bergerie.getSommets().get(_bergerie.getSommets().size()-1);
			polygon.addPoint((int)point1.getX(), (int)point1.getY());
			polygon.addPoint((int)point1.getX()+1, (int)point1.getY()+1);
			polygon.addPoint((int)point2.getX()+1, (int)point2.getY()+1);
			polygon.addPoint((int)point2.getX(), (int)point2.getY());
			int px1 = (point1.getX() > point2.getX())? (int)point2.getX():(int)point1.getX();
			int px2 = (point1.getX() > point2.getX())? (int)point1.getX():(int)point2.getX();
			int py1 = (point1.getY() > point2.getY())? (int)point2.getY():(int)point1.getY();
			int py2 = (point1.getY() > point2.getY())? (int)point1.getY():(int)point2.getY();
			for(int k=px1; k<px2; k++)
			{
				for(int l=py1; l<py2; l++)
				{
					if(polygon.contains(k, l))
					{
						initBuffer(k, l, 128, 128, 64);						
					}
				}
			}
		}
	}
	public void initBuffer(int px,int py, int r, int g, int b)
	{
		Buffer0[px][py][0]=r;
		Buffer0[px][py][1]=g;
		Buffer0[px][py][2]=b;
		Buffer1[px][py][0]=r;
		Buffer1[px][py][1]=g;
		Buffer1[px][py][2]=b;
	}
	private void initChiens()
	{
		this._chiens = new ArrayList<agent.Chien>();
		Chien chien= new Chien(this,new Coordonnees2D(50,100),5); 
		chien.setObjectif(new Coordonnees2D(this.objectif));
		this.addChien(chien);
	}
	
	private void initMoutons()
	{
		this._moutons = new ArrayList<Mouton>();
		//int nbMoutons = 30;
		int rayon = 5;
		for(int i=0; i<_nbMoutons; i++ )
		{
			int px=0,py=0;
			do{
				px =( (int) ((Math.random()*this.getWidth())) + rayon) % this.getWidth();
				py = ((int)(Math.random()*this.getHeight())+rayon)% this.getHeight();
			}while(this.isInObstacle( px, py) || this._bergerie.contient(new Coordonnees2D(px,py)));
			Mouton mouton= new Mouton(this,new Coordonnees2D(px,py),rayon); 
			//mouton.setObjectif(new Coordonnees2D(750,720));
			this.addMouton(mouton);
		}
	}
	public boolean mourir(int x, int y)
	{
		for(int i=0; i<this._lstObstacles.size(); i++)
		{
			if((_lstObstacles.get(i)).contient(new Coordonnees2D(x,y)) && (_lstObstacles.get(i)).tue())
			{
				return true;
			}
		}
		return false;
	}
	private boolean arriverAuBergerie(int x, int y)
	{
		if(this._bergerie.contient(new Coordonnees2D(x,y)))
		{
			return true;
		}
		return false;
	}
	public Bergerie getBergerie()
	{
		return this._bergerie;
	}
	public Coordonnees2D chercherMouton()
	{
		if(!this._moutons.isEmpty())
		{
			return new Coordonnees2D(this._moutons.get(0).getPosition());
		}
		return null;
	}
	public Coordonnees2D getObjectif()
	{
		return new Coordonnees2D(this.objectif);
	}
}
